package com.modules.config.integration.authenticator.sms;

import cn.hutool.core.util.StrUtil;
import com.common.bean.execption.UnloginException;
import com.common.cache.TimedLoaclCache;
import com.common.constant.SecurityConstants;
import com.common.enums.AuthTypeEnum;
import com.modules.config.integration.authenticator.sms.event.SmsAuthenticateBeforeEvent;
import com.modules.config.integration.authenticator.sms.event.SmsAuthenticateSuccessEvent;
import com.modules.config.integration.base.AbstractPreparableIntegrationAuthenticator;
import com.modules.config.integration.base.IntegrationAuthentication;
import com.modules.upms.entity.SysUser;
import com.modules.upms.entity.vo.AuthUserVO;
import com.modules.upms.service.SysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
import org.springframework.stereotype.Component;

/**
 * 短信验证码集成认证
 *
 * @author LIQIU
 * @date 2018-3-31
 **/
@Component
public class SmsIntegrationAuthenticator extends AbstractPreparableIntegrationAuthenticator implements  ApplicationEventPublisherAware {

    @Autowired
    private SysUserService sysUserService;
//
//    @Autowired
//    private VerificationCodeClient verificationCodeClient;

    @Autowired
    private PasswordEncoder passwordEncoder;

    private ApplicationEventPublisher applicationEventPublisher;

    @Override
    public AuthUserVO authenticate(IntegrationAuthentication integrationAuthentication) {

        //获取密码，实际值是验证码
        String password = integrationAuthentication.getAuthParameter("password");
        //获取用户名，实际值是手机号
        String username = integrationAuthentication.getUsername();
        //发布事件，可以监听事件进行自动注册用户
        this.applicationEventPublisher.publishEvent(new SmsAuthenticateBeforeEvent(integrationAuthentication));
        //通过手机号码查询用户
        SysUser sysUser = sysUserService.findUserByMobile(username);
        if (sysUser == null) {
            throw new UnloginException("手机号码不存在");
        } else {
            //将密码设置为验证码
            sysUser.setPassword(passwordEncoder.encode(password));
            //发布事件，可以监听事件进行消息通知
            this.applicationEventPublisher.publishEvent(new SmsAuthenticateSuccessEvent(integrationAuthentication));
        }
        return new AuthUserVO(sysUser);
    }

    @Override
    public void prepare(IntegrationAuthentication integrationAuthentication) {
        String smsCode = integrationAuthentication.getAuthParameter("password");
        String username = integrationAuthentication.getAuthParameter("username");

        String codeCacheKey = SecurityConstants.DEFAULT_CODE_KEY + username;

        String code = TimedLoaclCache.CODE_CACHE.get(codeCacheKey);

        if (!StrUtil.equals(smsCode, code)) {
            throw new OAuth2Exception("验证码错误或已过期");
        }
    }

    @Override
    public boolean support(IntegrationAuthentication integrationAuthentication) {
        return StrUtil.equals(integrationAuthentication.getAuthType(), AuthTypeEnum.WEB_SMS.getCode());
    }

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        this.applicationEventPublisher = applicationEventPublisher;
    }
}
